package handler

import (
	"doveclient/config"
	"doveclient/configschema"
	"doveclient/configwatcher"
	"doveclient/projconfig"
	"encoding/json"
	"hash/crc32"
	"io/ioutil"
	"strings"
)

func init() {
	handlers["GetConfigFileVerityCode"] = GetConfigFileVerityCode{}
}

type GetConfigFileVerityCode struct {
}

// 校验doveclient监听的
func (i GetConfigFileVerityCode) Process(args map[string]interface{}) (re []byte, err error) {
	// 是否获取配置项以及对应的值.
	var returnConfigValue bool

	var dirs []string = []string{}
	if args != nil {
		if _, ok := args["dirs"]; ok {
			if dirsList, ok := args["dirs"].([]interface{}); ok {
				for _, dir := range dirsList {
					dirs = append(dirs, dir.(string))
				}
			}
		} else {
			dirs = append(dirs, config.GetConfig().CONFIG_DIR...)
		}

		if _, ok := args["return_config_value"]; ok {
			returnConfigValue, _ = args["return_config_value"].(bool)
		}
	} else {
		dirs = append(dirs, config.GetConfig().CONFIG_DIR...)
	}

	var dbc *projconfig.DebugConfigs = nil
	if returnConfigValue && config.GetConfig().DEVMODE {
		dbc, err = projconfig.LoadDebugConfigs()
		if err != nil {
			return
		}
	}

	// 存储文件以及对应的校验值
	var fileVerifitionCode = make(map[string]interface{})
	// 存储配置项以及对应的值
	var configValue = make(map[string]interface{})
	// 存储特定文件下的配置项列表
	var configFileRef = make(map[string]interface{})

	for _, dir := range dirs {
		if dir == "/dev/null" {
			continue
		}

		files, cErr := ioutil.ReadDir(dir)
		if cErr != nil {
			fileVerifitionCode[dir] = nil
			configFileRef[dir] = nil
			continue
		}

		fileVerifitionCode[dir] = make(map[string]interface{})

		for _, file := range files {
			if file.IsDir() {
				continue
			}

			if strings.Index(file.Name(), ".schema.") == -1 {
				continue
			}

			fileName := strings.Replace(file.Name(), ".schema.", ".", -1)
			content, cErr := ioutil.ReadFile(dir + "/" + fileName)
			if cErr != nil {
				fileVerifitionCode[dir].(map[string]interface{})[fileName] = nil
				continue
			}

			fileVerifitionCode[dir].(map[string]interface{})[fileName] = crc32.ChecksumIEEE(content)

			// 需要获取每个schema文件引用的配置项以及对应的值.
			if returnConfigValue {
				if _, ok := configFileRef[dir]; !ok {
					configFileRef[dir] = make(map[string]interface{})
				}

				definedItems, cErr := configschema.ParseItems(dir + "/" + file.Name())
				if cErr != nil {
					configFileRef[dir].(map[string]interface{})[file.Name()] = nil
					continue
				}

				configFileRef[dir].(map[string]interface{})[file.Name()] = definedItems

				for _, configItem := range definedItems {
					if _, ok := configValue[configItem]; !ok {
						_, valuePlain, _, _, _, _, cErr := configwatcher.GetNewValueOfConfig(configItem, dbc, dir+"/"+file.Name())
						if cErr == nil {
							configValue[configItem] = valuePlain
						}
					}
				}
			}
		}
	}

	var result = make(map[string]interface{})
	result["file_verifition_code"] = fileVerifitionCode
	result["config_value"] = configValue
	result["config_file_ref"] = configFileRef

	re, err = json.Marshal(result)
	return
}
